using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui.ApplicationModel;

namespace MauiBuilder.Services;

/// <summary>
/// 日志管理类，负责记录应用程序运行日志
/// </summary>
public class LogManager
{
    private static LogManager? _instance;
    private readonly string _logFilePath;
    private readonly object _lockObj = new object();

    /// <summary>
    /// 获取LogManager单例实例
    /// </summary>
    public static LogManager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new LogManager();
            }
            return _instance;
        }
    }

    /// <summary>
    /// 构造函数，初始化日志文件路径
    /// </summary>
    private LogManager()
    {
        string logDirectory = Path.Combine(FileSystem.AppDataDirectory, "Logs");
        
        if (!Directory.Exists(logDirectory))
        {
            Directory.CreateDirectory(logDirectory);
        }

        string fileName = $"app_log_{DateTime.Now:yyyyMMdd}.log";
        _logFilePath = Path.Combine(logDirectory, fileName);
    }

    /// <summary>
    /// 获取应用程序的ServiceProvider
    /// </summary>
    /// <returns>IServiceProvider实例</returns>
    public static IServiceProvider GetServiceProvider()
    {
        try
        {
            var services = IPlatformApplication.Current?.Services;
            if (services == null)
            {
                Instance.LogWarning("无法获取ServiceProvider，IPlatformApplication.Current.Services为null");
                throw new InvalidOperationException("ServiceProvider不可用");
            }
            return services;
        }
        catch (Exception ex)
        {
            Instance.LogError("获取ServiceProvider时发生异常", ex);
            throw;
        }
    }

    /// <summary>
    /// 从ServiceProvider获取指定类型的服务实例
    /// </summary>
    /// <typeparam name="T">服务类型</typeparam>
    /// <returns>服务实例</returns>
    public static T GetService<T>()
        where T : class
    {
        try
        {
            var serviceProvider = GetServiceProvider();
            var service = serviceProvider.GetService<T>();
            if (service == null)
            {
                Instance.LogWarning($"无法从ServiceProvider获取服务类型: {typeof(T).Name}");
                throw new InvalidOperationException($"服务 {typeof(T).Name} 未注册");
            }
            return service;
        }
        catch (Exception ex)
        {
            Instance.LogError($"获取服务 {typeof(T).Name} 时发生异常", ex);
            throw;
        }
    }

    /// <summary>
    /// 记录信息日志
    /// </summary>
    /// <param name="message">日志消息</param>
    /// <param name="tag">日志标签</param>
    public void LogInfo(string message, string tag = "INFO")
    {
        WriteLog(tag, message);
    }

    /// <summary>
    /// 记录警告日志
    /// </summary>
    /// <param name="message">日志消息</param>
    /// <param name="tag">日志标签</param>
    public void LogWarning(string message, string tag = "WARNING")
    {
        WriteLog(tag, message);
    }

    /// <summary>
    /// 记录错误日志
    /// </summary>
    /// <param name="message">日志消息</param>
    /// <param name="exception">异常对象</param>
    /// <param name="tag">日志标签</param>
    public void LogError(string message, Exception? exception = null, string tag = "ERROR")
    {
        string logMessage = message;
        if (exception != null)
        {
            logMessage += $"\nException: {exception.Message}\nStackTrace: {exception.StackTrace}";
        }
        WriteLog(tag, logMessage);
    }

    /// <summary>
    /// 记录调试日志
    /// </summary>
    /// <param name="message">日志消息</param>
    /// <param name="tag">日志标签</param>
    public void LogDebug(string message, string tag = "DEBUG")
    {
#if DEBUG
        WriteLog(tag, message);
#endif
    }

    /// <summary>
    /// 写入日志到文件
    /// </summary>
    /// <param name="tag">日志标签</param>
    /// <param name="message">日志消息</param>
    private void WriteLog(string tag, string message)
    {
        try
        {
            string logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] [{tag}] {message}{Environment.NewLine}";
            
            lock (_lockObj)
            {
                File.AppendAllText(_logFilePath, logEntry);
            }

            // 在调试模式下同时输出到控制台
#if DEBUG
            Console.WriteLine(logEntry);
#endif
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to write log: {ex.Message}");
        }
    }

    /// <summary>
    /// 异步写入日志到文件
    /// </summary>
    /// <param name="tag">日志标签</param>
    /// <param name="message">日志消息</param>
    public async Task WriteLogAsync(string tag, string message)
    {
        try
        {
            string logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] [{tag}] {message}{Environment.NewLine}";
            
            await Task.Run(() =>
            {
                lock (_lockObj)
                {
                    File.AppendAllText(_logFilePath, logEntry);
                }
            });

            // 在调试模式下同时输出到控制台
#if DEBUG
            Console.WriteLine(logEntry);
#endif
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to write log: {ex.Message}");
        }
    }

    /// <summary>
    /// 清除过期日志文件
    /// </summary>
    /// <param name="daysToKeep">保留的天数</param>
    public void CleanupOldLogs(int daysToKeep = 7)
    {
        try
        {
            string? logDirectory = Path.GetDirectoryName(_logFilePath);
            if (Directory.Exists(logDirectory))
            {
                var files = Directory.GetFiles(logDirectory, "app_log_*.log");
                var cutoffDate = DateTime.Now.AddDays(-daysToKeep);

                foreach (var file in files)
                {
                    var fileInfo = new FileInfo(file);
                    if (fileInfo.CreationTime < cutoffDate)
                    {
                        fileInfo.Delete();
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to cleanup logs: {ex.Message}");
        }
    }
}